/*
 * Copyright (c) 2003-2010, Live Media Pty. Ltd.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, this list of
 *     conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list of
 *     conditions and the following disclaimer in the documentation and/or other materials
 *     provided with the distribution.
 *  3. Neither the name of Live Media nor the names of its contributors may be used to endorse
 *     or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
#include <inttypes.h>
#include <stdbool.h>
#include <endian.h>
#include <stdio.h>

#include "buffers.h"
#include "dictionary.h"
#include "common.h"
#include "type-protocol.h"
#include "argot-rpc.h"

#define OBJECT_COUNT 2

int32_t test_dosomething( int32_t a1 )
{
	TRACE("DO SOMETHING FUNCTION");
	return a1 * 3;
}

int processTestDoSomething()
{
	uint16_t id;
	int32_t a1;
	int32_t rv;
	
	TRACE("DOSOMETHING");
	
	id = read_u8();
	if ( id != 1 ) 
	{
		TRACE("INVALID ARGUMENT COUNT");
		return PROCESS_ERROR;
	}
	
	id = read_u16();
	if ( id != INT32 )
	{
		TRACE("INVALID ARGUMENT. EXPECTING S32");
		return PROCESS_ERROR;
	}
	
	a1 = (int32_t) read_u32();
	
	rv = test_dosomething( a1 );
	
	write_header( TYPE_MSG );
	send_u8( 0 );  // BOOL FALSE 
	send_u8( 1 ); // RESULT LENGTH 1
	send_u16( INT32 ); // TYPE - S32 
	send_u32( rv );  // VALUE
	return PROCESS_OK;
}

int processTest( int oid )
{
	uint16_t mid;
	
	TRACE("TEST INTERFACE");

	mid = read_u16();

	TRACE("TEST INTERFACE - method id - %i", mid);


	switch( mid )
	{
	case TEST_DOSOMETHING:
		return processTestDoSomething();
		break;
	default:
		TRACE( "UNKNOWN METHOD" );
		return PROCESS_ERROR;
	}
	return PROCESS_OK;
}
 
int processRpcReq()
{
	uint16_t id;
	uint16_t oid;
	int rc;
	
	TRACE("**PROCESS RPC");
	
	id = read_u8();  // TODO should be uvint28.
	if ( id != INDEX )
	{
		TRACE("**PROCESS RPC - not remote location index - %i - expected - %i", id, INDEX);
		return PROCESS_ERROR;
	}
	
	// Read the simple location identifier.
	oid = read_u16();
	if ( oid > OBJECT_COUNT )
	{
		TRACE("**PROCESS RPC - wrong object id - %i - expected - %i", oid, OBJECT_COUNT);
		return PROCESS_ERROR;
	}
	
	/*
	 * Later we might include a table of objects
	 * that we can index off.  Each unique interface
	 * for an object will be handled by a different
	 * function 
	 */
	 
	rc = processTest( oid );
	if ( rc == PROCESS_OK )
	{
	 	return PROCESS_OK;
	}
	return rc;
}
